# question_generator.py
import threading
from openai import OpenAI
from langchain.prompts import PromptTemplate
from typing import List
from config import API_KEY, BASE_URL, MODEL_NAME
from vector_processor import KnowledgeBaseProcessor
from knowledge_graph import KnowledgeGraphProcessor


class QuestionGenerator:
    """出题模块，负责根据知识库和知识图谱生成问题。"""

    def __init__(self, knowledge_processor: KnowledgeBaseProcessor, kg_processor: KnowledgeGraphProcessor,
                 kg_ready_event: threading.Event):
        self.kb_processor = knowledge_processor
        self.kg_processor = kg_processor
        self.kg_ready_event = kg_ready_event
        self.client = OpenAI(api_key=API_KEY, base_url=BASE_URL)
        self.generated_questions = []
        self.backup_questions = []
        self._init_prompt_templates()

    def _init_prompt_templates(self):
        """初始化用于生成问题的提示模板。"""
        self.question_prompt_template = PromptTemplate.from_template("""
        你是一名专业的考试出题老师，你的任务是根据提供的知识内容和相关信息生成一道考试题目。
        请严格按照以下要求进行：
        1. 问题必须是开放式问答题，不能是选择题或判断题。
        2. 问题必须与提供的知识内容和信息紧密相关。
        3. 问题应考察学生对知识点的理解、分析和应用能力。
        4. 根据给定的难度级别（easy/medium/hard），调整问题的深度和复杂性。
        5. 不要重复生成已有的问题。

        难度级别: {difficulty}
        知识内容: {context}
        相关知识图谱信息: {kg_info}

        请生成一个简洁、清晰的问题，可以直接用于考试。
        只输出问题本身，不要包含任何多余的解释或前缀。
        问题：
        """)

    def generate_question(self, difficulty: str = "medium") -> str:
        """生成一道问题。"""
        # 从知识库中随机选择一个关键词作为问题中心
        keywords = self.kb_processor.keywords
        if not keywords:
            return "无法生成问题，请检查知识库文件。"

        # 异步查询知识图谱
        kg_info = ""
        try:
            kg_info_thread = threading.Thread(target=self._query_kg_in_background, args=(keywords,))
            kg_info_thread.start()
        except Exception as e:
            print(f"后台知识图谱查询启动失败：{e}")

        # 等待知识图谱准备就绪
        self.kg_ready_event.wait(timeout=60)  # 设置超时时间
        if not self.kg_ready_event.is_set():
            print("Warning: Knowledge graph is not ready, generating question without KG info.")
        else:
            kg_info = self.kg_processor.query_graph(keywords)

        # 随机选择一个文档块作为上下文
        if not self.kb_processor.documents:
            return "无法生成问题，文档为空。"

        selected_doc = self.kb_processor.documents[0]
        context = selected_doc.page_content

        prompt = self.question_prompt_template.format(
            difficulty=difficulty,
            context=context,
            kg_info=kg_info
        )

        try:
            completion = self.client.chat.completions.create(
                model=MODEL_NAME,
                messages=[
                    {"role": "user", "content": prompt}
                ],
                max_tokens=200,
                temperature=0.7
            )
            return completion.choices[0].message.content.strip()
        except Exception as e:
            print(f"Failed to generate question: {e}")
            return "对不起，出题系统出现问题，请稍后再试。"

    def _query_kg_in_background(self, keywords: List[str]):
        """在后台线程中查询知识图谱，避免阻塞主线程。"""
        try:
            self.kg_processor.query_graph(keywords)
        except Exception as e:
            print(f"后台知识图谱查询失败：{e}")